package com.hsmpay.mobile.service.account.impl;

import com.hsmpay.common.pojo.BasePojo;
import com.hsmpay.common.pojo.qian4.Qian4SendLog;
import com.hsmpay.common.service.impl.BaseServiceSupport;
import com.hsmpay.common.util.DateConvertUtil;
import com.hsmpay.common.util.NumberUtil;
import com.hsmpay.common.util.OrderTypeUtil;
import com.hsmpay.common.util.bank.BankCardTypeUtil;
import com.hsmpay.mobile.action.account.fc.PurchaseBaseAction;
import com.hsmpay.mobile.action.account.scanCodePay.ScanCodePayParam;
import com.hsmpay.mobile.dao.bank.BankCodeDao;
import com.hsmpay.mobile.dao.brokerage.BrokEachOrderDao;
import com.hsmpay.mobile.dao.other.SettingsDao;
import com.hsmpay.mobile.dao.terminal.TchannelMDao;
import com.hsmpay.mobile.dao.trans.*;
import com.hsmpay.mobile.dao.user.UserMoneyDao;
import com.hsmpay.mobile.ds.*;
import com.hsmpay.mobile.ds.DS_ECBService;
import com.hsmpay.mobile.ds.DS_IdeaioeService;
import com.hsmpay.mobile.ds.DS_RuiShengGTService;
import com.hsmpay.mobile.ds.DS_RuiShengService;
import com.hsmpay.mobile.pojo.bank.BankCode;
import com.hsmpay.mobile.pojo.brokerage.BrokEachOrder;
import com.hsmpay.mobile.pojo.other.Settings;
import com.hsmpay.mobile.pojo.terminal.Tchannel;
import com.hsmpay.mobile.pojo.terminal.TchannelM;
import com.hsmpay.mobile.pojo.trans.AccountDetails;
import com.hsmpay.mobile.pojo.trans.TransAfterSettle;
import com.hsmpay.mobile.pojo.trans.TransOrder;
import com.hsmpay.mobile.pojo.trans.TransPriorSettle;
import com.hsmpay.mobile.pojo.user.UserMoney;
import com.hsmpay.mobile.service.account.AccountManageQ4Service;
import com.hsmpay.mobile.service.brokerage.BrokerageOrderService;
import com.hsmpay.qian4.service.ds.XYScanCodePayService;
import com.hsmpay.qian4.service.ds.ZYTLPayService;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.hsmpay.qian4.pojo.PurchaseResult;
import com.hsmpay.qian4.pojo.RevocationResult;

import javax.annotation.Resource;
import java.net.ConnectException;
import java.sql.SQLException;
import java.util.*;

/**
 * 账务管理  服务接口实现类 accountManageQ4Service
 */
@Service("accountManageQ4Service")
public class AccountManageQ4ServiceImpl extends BaseServiceSupport<BasePojo, Long> implements AccountManageQ4Service<BasePojo, Long> {
    @SuppressWarnings("unused")
    @Resource(name = "transAfterSettleDao")
    private TransAfterSettleDao<TransAfterSettle, Long> transAfterSettleDao;//结算后银行交易记录
    @Resource(name = "accountDetailsDao")
    private AccountDetailsDao<AccountDetails, Long> accountDetailsDao;//账户明细
    @Resource(name = "transOrderDao")
    private TransOrderDao<TransOrder, String> transOrderDao;//交易订单
    @Resource(name = "transPriorSettleDao")
    private TransPriorSettleDao<TransPriorSettle, Long> transPriorSettleDao;//transPriorSettleDao
    @Resource(name = "userMoneyDao")
    private UserMoneyDao<UserMoney, Long> userMoneyDao;
    @Resource(name = "qian4SendLogDao")
    private Qian4SendLogDao<Qian4SendLog, Long> qian4SendLogDao;//
    @Resource(name = "bankCodeDao")
    private BankCodeDao<BankCode, Long> bankCodeDao;
    @Resource(name = "brokEachOrderDao")
    private BrokEachOrderDao<BrokEachOrder, Long> brokEachOrderDao;//佣金dao
    @Resource(name = "ds_ECBService")
    public DS_ECBService<BasePojo, Long> ds_ECBService;//ECB
    @Resource(name = "ds_RuiShengService")
    public DS_RuiShengService<BasePojo, Long> ds_RuiShengService;//瑞升
    @Resource(name = "ds_RuiShengGTService")
    public DS_RuiShengGTService<BasePojo, Long> ds_RuiShengGTService;//瑞晟国通
    @Resource(name = "tchannelMDao")
    private TchannelMDao<TchannelM, Long> tchannelMDao;
    @Resource(name = "posPService")
    private DS_POSPService ds_pospService;
    @Resource(name = "ds_IdeaioeService")
    public DS_IdeaioeService<BasePojo, Long> ds_IdeaioeService;//E点支付
    @Resource(name = "ds_zytlPayService")
    public ZYTLPayService ds_zytlPayService;
    @Resource(name = "ds_YinShengBaoService")
    public DS_YinShengBaoService<BasePojo, Long> ds_yinShengBaoService;//银生宝
    @Resource(name = "ds_posService")
    public DS_POSService<BasePojo, Long> ds_posService;//大pos
    @Resource(name = "ds_ZHIFUTONGService")
    public DS_ZHIFUTONGService<BasePojo, Long> ds_zhifutongService;//支付通
    @Resource(name = "ds_HanXinService")
    public DS_HanXinService<BasePojo, Long> ds_HanXinService;//瑞鑫
    @Resource(name = "DS_ZhongLanService")
    public DS_ZhongLanService<BasePojo, Long> ds_zhongLanService;//中岚
    @Resource(name = "DS_KaYinKaService")
    public DS_KaYinKaService<BasePojo, Long> ds_kaYinKaService;//卡银卡
    @Resource(name="settingsDao")
    private SettingsDao<Settings,Long> settingsDao;//配置
    @Resource(name="ds_XYScanCodePayService")
    public XYScanCodePayService ds_XYScanCodePayService;
    @Resource(name="brokerageOrderService")
    public BrokerageOrderService brokerageOrderService;

    private static org.slf4j.Logger log = LoggerFactory.getLogger(AccountManageQ4ServiceImpl.class);

    /**
     * 提前下单  并保存数据
     *
     * @param transOrder       订单信息
     * @param send             日志信息
     * @param collectionTypeId 通道ID
     * @return
     * @throws Exception
     */
    public TransPriorSettle advanceOrder(TransOrder transOrder, Qian4SendLog send, Integer collectionTypeId) throws Exception {
        send.setCallType(0);//前端调用
        send.setUserId(transOrder.getUserId());
        //保存将要发送的数据
        Long sendId = qian4SendLogDao.insertEntity(send);
        send.setId(sendId);

        //下订单 我要收款 订单状态是 正在处理中
        transOrderDao.insertEntity(transOrder);

        //添加发送记录
        TransPriorSettle transPriorSettle = new TransPriorSettle();
        transPriorSettle.setOrderNum(transOrder.getOrderNum());
        transPriorSettle.setStatus(3);//交易状态  银行处理中 未付款
        transPriorSettle.setCollectionType(collectionTypeId);
        transPriorSettle.setSendId(sendId);
        transPriorSettle.setMerchantOrderId(send.getMerchantOrderId());
        transPriorSettle.setMerchantOrderTime(send.getMerchantOrderTime());
        transPriorSettle.setTerminalId(send.getTerminalId());
        transPriorSettle.setMerchantId(send.getMerchantId());//商户号
        if (BankCardTypeUtil.isCreditCard(transOrder.getBankCard())) {//是否是信用卡
            transPriorSettle.setIsCreditCard(1);
        } else {
            transPriorSettle.setIsCreditCard(0);
        }

        Long transPId = transPriorSettleDao.insertEntity(transPriorSettle);
        transPriorSettle.setId(transPId);

        return transPriorSettle;
    }

    /**
     * 解析收款结果
     *
     * @param pr
     * @param orgId
     * @return
     * @throws Exception
     */
    public TransPriorSettle purchaseResolveResult(TransPriorSettle transPs, Qian4SendLog send, PurchaseResult pr, Tchannel tc, Long orgId) throws Exception {
        transPs.setIssueBank(pr.getIssueBank());//发卡行名称
        transPs.setCardType(pr.getCardType());//卡类别
        transPs.setExpireDate(pr.getExpireDate());//有效期
        transPs.setBankOrderNum(pr.getBankOrderNum());//交易流水号
        transPs.setBatchId(pr.getBatchId());//批次号
        transPs.setSearchId(pr.getSearchId());//查询号
        transPs.setAuthorizationCode(pr.getAuthorizationCode());//授权号
        transPs.setBankRef(pr.getBankRef());//参考和
        transPs.setResponseCode(pr.getReqCode());//应答码
        transPs.setBankMessage(pr.getReqMsg());//应答码描述

        send.setIssueBank(pr.getIssueBank());//发卡行名称
        send.setCardType(pr.getCardType());//卡类别
        send.setExpireDate(pr.getExpireDate());//有效期
        send.setBankOrderNum(pr.getBankOrderNum());//交易流水号
        send.setBatchId(pr.getBatchId());//批次号
        send.setSearchId(pr.getSearchId());//查询号
        send.setAuthorizationCode(pr.getAuthorizationCode());//授权号
        send.setBankRef(pr.getBankRef());//参考和
        send.setResponseCode(pr.getReqCode());//应答码
        send.setBankMessage(pr.getReqMsg());//应答码描述

        if ("0000".equals(transPs.getResponseCode())) {//银联处理成功
            transPs.setStatus(1);

            TransOrder order = new TransOrder();
            order.setOrderNum(transPs.getOrderNum());
            order = transOrderDao.searchEntity(order);
            /**
             * 正常收款订单,收款完成之后,标记该笔收款订单 status:1 交易成功 clearing:1 结算
             *      零费率收款订单 ,收款完成后, 标记该笔收款订单 status:1 交易成功 clearing:0 未结算
             *          当零费率订单收款金额到用户账单上之后,修改该笔收款订单的clearing为1 结算
             */
            if (11l == order.getOrderTypeId()) {
                transOrderDao.updateStatusClearing(transPs.getOrderNum(), 1, 0);
            } else {
                transOrderDao.updateStatusClearing(transPs.getOrderNum(), 1, 1);
            }
            if (order.getOrderTypeId().equals(OrderTypeUtil.RECEIVABLES) || order.getOrderTypeId().equals(OrderTypeUtil.SECONDSTO)) {//如果是收款  才在虚拟货币表里添加
                if (null == transPs.getIssueBank()) {//发卡行名称
                    transPs.setIssueBank(bankCodeDao.searchBankNameByCard(order.getBankCard()));
                }
                if (transPs.getCollectionType() == PurchaseBaseAction.TC_ZHONGYI) {
                    transPs.setTerminalId(send.getTerminalId());
                    transPs.setMerchantId(send.getMerchantId());
                }
                double revenueFeeMoney = getRevenueFeeMoney(transPs, tc, order.getTransMoney());
                double receivableMoney = NumberUtil.round56((order.getTransMoney() - revenueFeeMoney));
                order.setRevenueFeeMoney(revenueFeeMoney);//千48 收款
                order.setReceivableMoney(receivableMoney);//利润
                //修改 订单
                transOrderDao.updateRevenueFeeMoneyByNum(order);

                updateUserMoney(order, 1, order.getChargeAmount());
                //调用佣金存储过程
                //零费率交易不需要计算佣金  秒到配置为0的情况 不计算佣金
                if (whetherSSProBrok(order.getOrderTypeId())) {
                    int clientType = 2;
                    if(order.getClientType() == 7){
                        clientType = 7;
                    }
                    int status = brokEachOrderDao.proBrokMobile(order.getRoleId(), 1, orgId, order.getTransMoney(), order.getFeeMoney(), order.getFeeRate(), order.getOrderNum(), clientType, order.getCreateDate(), revenueFeeMoney, order.getUserId());

//                    int status = brokEachOrderDao.proBrokMobile(order.getRoleId(), 1, orgId, order.getTransMoney(), order.getFeeMoney(), order.getFeeRate(), order.getOrderNum(), 2, order.getCreateDate(), revenueFeeMoney, order.getUserId());
                   //如果代理商所得佣金大于100元,则生成佣金结算订单
                    log.info("生成当前佣金订单的收款订单号: " + order.getOrderNum());
                   if(1 == status){
                       BrokEachOrder brokEachOrder = new BrokEachOrder();
                       brokEachOrder.setOrderNum(order.getOrderNum());
                       List<BrokEachOrder> brokEachOrderList = brokEachOrderDao.searchEntityList(brokEachOrder);
                       if(brokEachOrderList.size() > 0){
                            for(BrokEachOrder beo : brokEachOrderList){
                                Long organizationId = beo.getOrganizationId();
                                brokEachOrder = new BrokEachOrder();
                                brokEachOrder.setOrganizationId(organizationId);
                                brokEachOrder.setClearStatus(3);
                                List<BrokEachOrder> brokEachOrders = brokEachOrderDao.searchEntityList(brokEachOrder);
                                if(brokEachOrders.size() > 0){
                                    Double totalBrok = 0.00;
                                    for(BrokEachOrder orgBeo : brokEachOrders){
                                        //如果单笔所得佣金为0,则直接标记已结算,避免查询冗余数据
                                        if(orgBeo.getBrokerage() == 0.00){
                                            orgBeo.setClearStatus(1);
                                            brokEachOrderDao.updateClearStatusById(orgBeo);
                                            continue;
                                        }
                                        totalBrok += orgBeo.getBrokerage();
                                    }
                                    if(totalBrok >= 100){
                                        Map map = new HashMap();
                                        map.put("organizationId",organizationId);
                                        map.put("clearStatus",3);
                                        BrokEachOrder beoDate = brokEachOrderDao.minAndMaxCreatDateInTransOrder(map);

                                        Calendar startCalendar = Calendar.getInstance();
                                        startCalendar.setTime(beoDate.getMinDate());
                                        startCalendar.add(Calendar.SECOND, 2);

                                        Calendar endCalendar = Calendar.getInstance();
                                        endCalendar.setTime(beoDate.getMaxDate());
                                        endCalendar.add(Calendar.SECOND, 1);

                                        map.put("startDate",startCalendar.getTime());
                                        map.put("endDate",endCalendar.getTime());
                                        log.info("去生成机构: " + organizationId + " 待结算佣金: "+NumberUtil.roundF2(totalBrok)+" 的佣金结算订单!");
                                        brokerageOrderService.generateBrokerageOrder(map);
                                    }else {
                                        log.info("当前机构: " + organizationId +" 待结算佣金: "+ NumberUtil.roundF2(totalBrok) +" 不足一百,暂不生成佣金结算订单!");
                                    }
                                }else {
                                    log.info("当前机构: " + organizationId +" 暂无佣金订单!");
                                }

                            }
                       }
                   }
                }
            }
        } else {
            transPs.setStatus(0);
            transOrderDao.updateStatusClearing(transPs.getOrderNum(), 0, null);
        }

        transPriorSettleDao.updateEntity(transPs);
        qian4SendLogDao.updateByResult(send);
        return transPs;
    }


    /**
     * 获取秒到收款 是否计算佣金
     * @return
     */
    public boolean whetherSSProBrok(Long orderTypeId) throws SQLException {
        boolean result = false;

        Settings settings = new Settings();
        settings.setFunctionKey("SECONDSTO_PRO_BROK");
        settings = settingsDao.searchEntity(settings);

        if (orderTypeId != 12l || (null != settings && "1".equals(settings.getMainValue()))){
            result = true;
        }

        return result;
    }


    /**
     * 计算 渠道方
     *
     * @param transPs
     * @param tc
     * @param transMoney
     * @return
     */
    public double getRevenueFeeMoney(TransPriorSettle transPs, Tchannel tc, Double transMoney) {
        double revenueFeeMoney = 0.0;
        double feeRate = tc.getFeeRate();
        double fdMaxFee = tc.getFdMaxFee();
        double fdMinFee = tc.getFdMinFee();
        long roleId = 0l;
        try {
            TchannelM tcm = tchannelMDao.searchTchannelMByCode(transPs.getCollectionType(), transPs.getMerchantId(), transPs.getTerminalId());
            if (null != tcm) {
                feeRate = tcm.getFeeRate();
                roleId = tcm.getRoleId();
                if (roleId != 2) {
                    fdMaxFee = tcm.getFdMaxFee();
                    fdMinFee = tcm.getFdMinFee();
                }
            }

            revenueFeeMoney = NumberUtil.round56((transMoney * feeRate));

            if (roleId != 2) {
                if (0 != fdMaxFee && revenueFeeMoney > fdMaxFee) {//如果 大于封顶值 那么就等于封顶值
                    revenueFeeMoney = fdMaxFee;
                }
                if (0 != fdMinFee && revenueFeeMoney < fdMinFee) {//如果 如果小于最低渠道商手续费 就按最低渠道商手续费算
                    revenueFeeMoney = fdMinFee;
                }
            }
            return revenueFeeMoney;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return revenueFeeMoney;
    }

    /**
     * 我要收款 失败
     *
     * @param transPs
     * @param resCode
     * @param resMsg
     * @return
     * @throws Exception
     */
    public int receivablesError(TransPriorSettle transPs, String resCode, String resMsg) throws Exception {
        //修改 订单为失败订单
        transOrderDao.updateStatusClearing(transPs.getOrderNum(), 0, null);
        //修改 收款状态为失败  并保存响应代码 和 描述
        transPs.setStatus(0);
        transPs.setResponseCode(resCode);
        transPs.setBankMessage(resMsg);
        return transPriorSettleDao.updateEntity(transPs);
    }

    /**
     * 判断是否 可以撤销
     * status 1 成功  0 失败  2 无法撤销
     *
     * @param send
     * @return
     * @throws Exception
     */
    @SuppressWarnings("deprecation")
    public Map<String, Object> isCanRevocationOrder(Qian4SendLog send) throws Exception {
        Map<String, Object> resMap = new HashMap<String, Object>();
        resMap.put("status", 0);
        String reqCode = "8888";
        String reqMsg = "不存在此订单";
        TransPriorSettle transPs = transPriorSettleDao.searchTransPriorSettle(send.getTerminalId(), send.getOrgMerchantOrderId());

        if (null == transPs) {
            resMap.put("reqCode", reqCode);
            resMap.put("reqMsg", reqMsg);
            return resMap;
        }
        TransOrder transOrder = new TransOrder();
        transOrder.setOrderNum(transPs.getOrderNum());
        transOrder = transOrderDao.searchEntity(transOrder);
        if (6 == transOrder.getStatus().intValue() || 7 == transOrder.getStatus().intValue()) {
            resMap.put("reqCode", reqCode);
            resMap.put("reqMsg", "此订单已经撤销了！");
            return resMap;
        }

        Date date = new Date();

        //判断 撤销时间
        String orderDate = DateConvertUtil.dateString(transOrder.getCreateDate());
        Date startDate = DateConvertUtil.stringDateTime(orderDate + " 22:40:00");
        Date tempDate = DateConvertUtil.getSpecifiedDayAfter(transOrder.getCreateDate());
        Date stopDate = DateConvertUtil.stringDateTime(DateConvertUtil.dateString(tempDate) + " 22:40:00");

        if (transOrder.getCreateDate().getTime() < startDate.getTime()) {
            if (date.getTime() > startDate.getTime()) {
                resMap.put("reqCode", reqCode);
                resMap.put("reqMsg", "此订单已经过了一个结算周期，不能结算！");
                return resMap;
            }
        } else {
            if (date.getTime() > stopDate.getTime()) {
                resMap.put("reqCode", reqCode);
                resMap.put("reqMsg", "此订单已经过了一个结算周期，不能结算！");
                return resMap;
            }
        }
        resMap.put("status", 1);
        return resMap;
    }

    /**
     * 为了解决事务  问题  暂时把日志信息在anction中添加
     * 取消订单  并保存数据
     *
     * @param send
     * @return status 1 成功  0 失败  2 无法撤销
     * @throws Exception
     */
    public Map<String, Object> revocationOrder(Qian4SendLog send) throws Exception {
        Map<String, Object> resMap = new HashMap<String, Object>();
        resMap.put("status", 1);
        String reqCode = "8888";
        String reqMsg = "不存在此订单";
        TransPriorSettle transPs = transPriorSettleDao.searchTransPriorSettle(send.getTerminalId(), send.getOrgMerchantOrderId());

        if (null == transPs) {
            resMap.put("status", 0);
            resMap.put("reqCode", reqCode);
            resMap.put("reqMsg", reqMsg);
            return resMap;
        }
        TransOrder transOrder = new TransOrder();
        transOrder.setOrderNum(transPs.getOrderNum());
        transOrder = transOrderDao.searchEntity(transOrder);
        if (6 == transOrder.getStatus().intValue()) {
            resMap.put("reqCode", reqCode);
            resMap.put("reqMsg", "此订单已经撤销了！");
            return resMap;
        }

        //判断 撤销时间
        String orderDate = DateConvertUtil.dateString(transOrder.getCreateDate());
        Date startDate = DateConvertUtil.stringDateTime(orderDate + " 22:40:00");
        Date tempDate = DateConvertUtil.getSpecifiedDayAfter(transOrder.getCreateDate());
        Date stopDate = DateConvertUtil.stringDateTime(DateConvertUtil.dateString(tempDate) + " 22:40:00");
        Date date = new Date();
        if (transOrder.getCreateDate().getTime() < startDate.getTime()) {
            if (date.getTime() > startDate.getTime()) {
                resMap.put("reqCode", reqCode);
                resMap.put("reqMsg", "此订单已经过了一个结算周期，不能结算！");
                return resMap;
            }
        } else {
            if (date.getTime() > stopDate.getTime()) {
                resMap.put("reqCode", reqCode);
                resMap.put("reqMsg", "此订单已经过了一个结算周期，不能结算！");
                return resMap;
            }
        }

        //修改 撤销ID
        transPs.setRevocationSendId(send.getId());
        transPriorSettleDao.updateEntity(transPs);
        //删除佣金表 对于这笔佣金的记录
        brokEachOrderDao.deleteBrokEachOrderByOrderNum(transPs.getOrderNum());
        try {
            RevocationResult rs = null;
            switch (transPs.getCollectionType()) {
                case PurchaseBaseAction.TC_ECB:
                    rs = ds_ECBService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_RuiSheng:
                    rs = ds_RuiShengService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_RuiSheng_GT:
                    rs = ds_RuiShengGTService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_ZHONGYI:
                    rs = ds_zytlPayService.revocation(send);
                    break;
                case PurchaseBaseAction.TC_POSP:
                    rs = ds_pospService.unBillPayment(send);
                    break;

                case PurchaseBaseAction.TC_EPOINT://E点
                    rs = ds_IdeaioeService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_YinShengBao:
                    rs = ds_yinShengBaoService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_POS:
                    rs = ds_posService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_ZHIFUTONG:
                    rs = ds_zhifutongService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_HANXIN:
                    rs = ds_HanXinService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_ZHONGLAN:
                    rs = ds_zhongLanService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_KAYINKA:
                    rs = ds_kaYinKaService.unBillPayment(send);
                    break;
            }

            String responseCode = rs.getReqCode();//应答码
            String bankMessage = rs.getReqMsg();//应答码描述
            if (rs.getStatus() == 1 && "0000".equals(rs.getReqCode())) {//
                //修改 订单为失败订单
                transOrderDao.updateStatusClearing(transPs.getOrderNum(), 6, null);
                //修改 收款状态为失败  并保存响应代码 和 描述
                transPs.setStatus(0);
                transPriorSettleDao.updateEntity(transPs);
                resMap.put("status", 1);
                resMap.put("reqCode", "0001");//注意  不能让客户端显示小票
                resMap.put("bankTransTime", null == rs.getBankTransTime() ? "" : rs.getBankTransTime());
                resMap.put("expireDate", null == rs.getExpireDate() ? "" : rs.getExpireDate());
                resMap.put("bankOrderNum", null == rs.getBankOrderNum() ? "" : rs.getBankOrderNum());
                resMap.put("batchId", null == rs.getBatchId() ? "" : rs.getBatchId());
                resMap.put("searchId", null == rs.getSearchId() ? "" : rs.getSearchId());
                resMap.put("authorizationCode", null == rs.getAuthorizationCode() ? "" : rs.getAuthorizationCode());
                resMap.put("bankRef", null == rs.getBankRef() ? "" : rs.getBankRef());
                resMap.put("accountNumber", null == rs.getAccountNumber() ? "" : rs.getAccountNumber());
                resMap.put("bankTransDate", null == rs.getBankTransDate() ? "" : rs.getBankTransDate());

                resMap.put("reqMsg", "由于网络原因，交易已撤销！");
            } else {
                resMap.put("status", 0);
                resMap.put("reqCode", responseCode);
                resMap.put("reqMsg", "交易撤销失败！");//StringUtils.isEmpty(bankMessage) ? "交易撤销失败！" : bankMessage

                if (!"9999".equals(responseCode)) {//撤销失败
                    transOrderDao.updateStatusClearing(transPs.getOrderNum(), 10, null);
                }
            }
            qian4SendLogDao.updateResCodeMassage(send.getId(), responseCode, bankMessage);
        } catch (ConnectException e) {//请求 超时
            send.timeOut++;
            throw e;
        }
        return resMap;
    }

    /**
     * 用于中亿在服务器端发起撤消交易
     *
     * @param send
     * @return
     * @throws Exception
     */
    public Map<String, Object> revocationOrderForZY(Qian4SendLog send) throws Exception {
        Map<String, Object> resMap = new HashMap<String, Object>();
        resMap.put("status", 1);
        String reqCode = "8888";
        String reqMsg = "不存在此订单";
        TransPriorSettle transPs = transPriorSettleDao.searchTransPriorSettle(send.getTerminalId(), send.getOrgMerchantOrderId());

        if (null == transPs) {
            resMap.put("status", 0);
            resMap.put("reqCode", reqCode);
            resMap.put("reqMsg", reqMsg);
            return resMap;
        }
        TransOrder transOrder = new TransOrder();
        transOrder.setOrderNum(transPs.getOrderNum());
        transOrder = transOrderDao.searchEntity(transOrder);
        if (6 == transOrder.getStatus().intValue()) {
            resMap.put("reqCode", reqCode);
            resMap.put("reqMsg", "此订单已经撤销了！");
            return resMap;
        }

        //判断 撤销时间
        String orderDate = DateConvertUtil.dateString(transOrder.getCreateDate());
        Date startDate = DateConvertUtil.stringDateTime(orderDate + " 22:40:00");
        Date tempDate = DateConvertUtil.getSpecifiedDayAfter(transOrder.getCreateDate());
        Date stopDate = DateConvertUtil.stringDateTime(DateConvertUtil.dateString(tempDate) + " 22:40:00");
        Date date = new Date();
        if (transOrder.getCreateDate().getTime() < startDate.getTime()) {
            if (date.getTime() > startDate.getTime()) {
                resMap.put("reqCode", reqCode);
                resMap.put("reqMsg", "此订单已经过了一个结算周期，不能结算！");
                return resMap;
            }
        } else {
            if (date.getTime() > stopDate.getTime()) {
                resMap.put("reqCode", reqCode);
                resMap.put("reqMsg", "此订单已经过了一个结算周期，不能结算！");
                return resMap;
            }
        }

        //修改 撤销ID
        transPs.setRevocationSendId(send.getId());
        transPriorSettleDao.updateEntity(transPs);
        //删除佣金表 对于这笔佣金的记录
        brokEachOrderDao.deleteBrokEachOrderByOrderNum(transPs.getOrderNum());
        try {
            RevocationResult rs = null;
            switch (transPs.getCollectionType()) {
                case PurchaseBaseAction.TC_ECB:
                    rs = ds_ECBService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_RuiSheng:
                    rs = ds_RuiShengService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_RuiSheng_GT:
                    rs = ds_RuiShengGTService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_ZHONGYI:
                    rs = ds_zytlPayService.revocation(send);
                    break;
                case PurchaseBaseAction.TC_POSP:
                    rs = ds_pospService.unBillPayment(send);
                    break;

                case PurchaseBaseAction.TC_EPOINT://E点
                    rs = ds_IdeaioeService.unBillPayment(send);
                    break;
                case PurchaseBaseAction.TC_YinShengBao:
                    rs = ds_yinShengBaoService.unBillPayment(send);
                    break;
            }

            String responseCode = rs.getReqCode();//应答码
            String bankMessage = rs.getReqMsg();//应答码描述
            if (rs.getStatus() == 1 && "0000".equals(rs.getReqCode())) {//
                //修改 订单为失败订单
                transOrderDao.updateStatusClearing(transPs.getOrderNum(), 6, null);
                //修改 收款状态为失败  并保存响应代码 和 描述
                transPs.setStatus(0);
                transPriorSettleDao.updateEntity(transPs);
                resMap.put("status", 1);
                resMap.put("reqCode", "0000");//服务端调用  不用考虑小票问题
                resMap.put("bankTransTime", null == rs.getBankTransTime() ? "" : rs.getBankTransTime());
                resMap.put("expireDate", null == rs.getExpireDate() ? "" : rs.getExpireDate());
                resMap.put("bankOrderNum", null == rs.getBankOrderNum() ? "" : rs.getBankOrderNum());
                resMap.put("batchId", null == rs.getBatchId() ? "" : rs.getBatchId());
                resMap.put("searchId", null == rs.getSearchId() ? "" : rs.getSearchId());
                resMap.put("authorizationCode", null == rs.getAuthorizationCode() ? "" : rs.getAuthorizationCode());
                resMap.put("bankRef", null == rs.getBankRef() ? "" : rs.getBankRef());
                resMap.put("accountNumber", null == rs.getAccountNumber() ? "" : rs.getAccountNumber());
                resMap.put("bankTransDate", null == rs.getBankTransDate() ? "" : rs.getBankTransDate());

                resMap.put("reqMsg", "交易撤销成功!");
            } else {
                resMap.put("status", 0);
                resMap.put("reqCode", responseCode);
                resMap.put("reqMsg", "交易撤销失败！");

                if (!"9999".equals(responseCode)) {//撤销失败
                    transOrderDao.updateStatusClearing(transPs.getOrderNum(), 10, null);
                }
            }
            qian4SendLogDao.updateResCodeMassage(send.getId(), responseCode, bankMessage);
        } catch (ConnectException e) {//请求 超时
            send.timeOut++;
            throw e;
        }
        return resMap;
    }

    /**
     * 添加用户明细信息
     * 修改虚拟货币
     *
     * @param transOrder 订单对象
     * @param incExp     1收入 0为支出（对于虚拟货币）
     * @param money      收入 支出的钱
     * @return
     * @throws Exception
     */
    //修改明细表
    public int updateUserMoney(TransOrder transOrder, int incExp, double money) throws Exception {
        UserMoney userMoney = userMoneyDao.searchUserMoneyByUserId(transOrder.getUserId());

        AccountDetails accountDetails = new AccountDetails();
        accountDetails.setOrderNum(transOrder.getOrderNum());
        accountDetails.setUserId(transOrder.getUserId());
        if (transOrder.getRoleId() == 4L) {
            // accountDetails.setBalance(userMoney.getMoney());
            // 零费率交易无需更新余额
        } else {
            if (1 == incExp) {
                accountDetails.setBalance(userMoney.getMoney() + money);
            } else {
                accountDetails.setBalance(userMoney.getMoney() - money);
            }
        }
        accountDetails.setIncExp(incExp);//收入1收入 0为支出
        accountDetails.setTransMoney(money);
        accountDetails.setCreateDate(transOrder.getCreateDate());
        accountDetailsDao.insertEntity(accountDetails);
        //银行处理成功 就修改账户虚拟货币

        userMoney = new UserMoney();
        userMoney.setUserId(transOrder.getUserId());
        if (transOrder.getRoleId() != 4L) { // 当用户为零费率时,金额不变化
            if (1 == incExp) {
                userMoney.setMoney(money);
            } else {
                userMoney.setMoney(0 - money);
                //userMoney.setFreezeMoney(money);
            }
        }
        return userMoneyDao.updateUserMoneyByUserId(userMoney);
    }

    /**
     * 为了解决事务  问题  暂时把日志信息在anction中添加
     * 取消订单  并保存数据
     *
     * @param send
     * @return status 1 成功  0 失败  2 无法撤销
     * @throws Exception
     */
    public Map<String, Object> scanRevocationOrder(Qian4SendLog send, ScanCodePayParam scanCodePayParam) throws Exception {
        Map<String, Object> resMap = new HashMap<String, Object>();
        resMap.put("status", 1);
        String reqCode = "8888";
        String reqMsg = "不存在此订单";
        TransPriorSettle transPs = transPriorSettleDao.searchTransPriorSettle(send.getTerminalId(), send.getOrgMerchantOrderId());

        if (null == transPs) {
            resMap.put("status", 0);
            resMap.put("reqCode", reqCode);
            resMap.put("reqMsg", reqMsg);
            return resMap;
        }
        TransOrder transOrder = new TransOrder();
        transOrder.setOrderNum(transPs.getOrderNum());
        transOrder = transOrderDao.searchEntity(transOrder);
        if (6 == transOrder.getStatus().intValue()) {
            resMap.put("reqCode", reqCode);
            resMap.put("reqMsg", "此订单已经撤销了！");
            return resMap;
        }

        //判断 撤销时间
        String orderDate = DateConvertUtil.dateString(transOrder.getCreateDate());
        Date startDate = DateConvertUtil.stringDateTime(orderDate + " 22:40:00");
        Date tempDate = DateConvertUtil.getSpecifiedDayAfter(transOrder.getCreateDate());
        Date stopDate = DateConvertUtil.stringDateTime(DateConvertUtil.dateString(tempDate) + " 22:40:00");
        Date date = new Date();
        if (transOrder.getCreateDate().getTime() < startDate.getTime()) {
            if (date.getTime() > startDate.getTime()) {
                resMap.put("reqCode", reqCode);
                resMap.put("reqMsg", "此订单已经过了一个结算周期，不能结算！");
                return resMap;
            }
        } else {
            if (date.getTime() > stopDate.getTime()) {
                resMap.put("reqCode", reqCode);
                resMap.put("reqMsg", "此订单已经过了一个结算周期，不能结算！");
                return resMap;
            }
        }

        //修改 撤销ID
        transPs.setRevocationSendId(send.getId());
        transPriorSettleDao.updateEntity(transPs);
        //删除佣金表 对于这笔佣金的记录
        brokEachOrderDao.deleteBrokEachOrderByOrderNum(transPs.getOrderNum());
        try {
            RevocationResult rs = null;
            switch (transPs.getCollectionType()) {
                case 83://微信扫码支付
                    rs = ds_XYScanCodePayService.revocation(scanCodePayParam.getOutTradeNo());
                    break;
            }

            String responseCode = rs.getReqCode();//应答码
            String bankMessage = rs.getReqMsg();//应答码描述
            if (rs.getStatus() == 1 && "0000".equals(rs.getReqCode())) {//
                //修改 订单为失败订单
                transOrderDao.updateStatusClearing(transPs.getOrderNum(), 6, null);
                //修改 收款状态为失败  并保存响应代码 和 描述
                transPs.setStatus(0);
                transPriorSettleDao.updateEntity(transPs);
                resMap.put("status", 1);
                resMap.put("reqCode", "0001");//注意  不能让客户端显示小票
                resMap.put("bankTransTime", null == rs.getBankTransTime() ? "" : rs.getBankTransTime());
                resMap.put("expireDate", null == rs.getExpireDate() ? "" : rs.getExpireDate());
                resMap.put("bankOrderNum", null == rs.getBankOrderNum() ? "" : rs.getBankOrderNum());
                resMap.put("batchId", null == rs.getBatchId() ? "" : rs.getBatchId());
                resMap.put("searchId", null == rs.getSearchId() ? "" : rs.getSearchId());
                resMap.put("authorizationCode", null == rs.getAuthorizationCode() ? "" : rs.getAuthorizationCode());
                resMap.put("bankRef", null == rs.getBankRef() ? "" : rs.getBankRef());
                resMap.put("accountNumber", null == rs.getAccountNumber() ? "" : rs.getAccountNumber());
                resMap.put("bankTransDate", null == rs.getBankTransDate() ? "" : rs.getBankTransDate());

                resMap.put("reqMsg", "由于网络原因，交易已撤销！");
            } else {
                resMap.put("status", 0);
                resMap.put("reqCode", responseCode);
                resMap.put("reqMsg", "交易撤销失败！");//StringUtils.isEmpty(bankMessage) ? "交易撤销失败！" : bankMessage

                if (!"9999".equals(responseCode)) {//撤销失败
                    transOrderDao.updateStatusClearing(transPs.getOrderNum(), 10, null);
                }
            }
            qian4SendLogDao.updateResCodeMassage(send.getId(), responseCode, bankMessage);
        } catch (ConnectException e) {//请求 超时
            send.timeOut++;
            throw e;
        }
        return resMap;
    }

    //---------------------set get start--------------------
    //---------------------set get end----------------------
}
